home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
basic
/
UDP_Chat.lha
/
UDPChat
/
UDP_ChatV2.3.asc
< prev
next >
Wrap
Text File
|
1999-03-29
|
40KB
|
1,088 lines
;
; UDP Chat code V2.3 7/03/99
;
; This code sends and receives UDP data packets like a
; a simple IRC client, and checks wether they have arrived
; at their destination, and allows other copies of this
; program to log in to this one (can act as a server or client).
;
; Written by Anton Reinauer <anton@ww.co.nz>.
; GUI: Alvaro Thompson <alvaro@enterprise.net> - And awful hacks
; by me to his nice font sensitive code :-)
; - typical bloody games programmer ;-)
;
; Thanks to Paul Burkey for TCP_Funcs and to Dr. Ercole Spiteri
; for TCP-to-Blitz.
;
; ARexx portname: "UDP_Chat"
;
; Turn overflow errors off in Debugger options,
; and have amigalibs.res resident in compiler options.
WBStartup
NoCli
Hostname.s="localhost" ; "localhost" default destination host address
#PORT=27272 ; 27272 default destination port to send data to
#LOCALPORT=27272 ; 27272
#NO_CONNECTION=1 ; 0 - are we connected, or have we been connected to the Internet since bootup?
; - 1 for not been connected, 0 for have/are connected.
#DEBUG=1 ; 1 - 1 for debug info and multiple local copies
#MAX_NUMBER_PLAYERS=8 ; 8
#MESSAGE_ARRAY_SIZE=100 ; 256
GAME_NAME.s="UDP_Chat" ; "UDP_Chat" Game name (for login)
PORT_NAME.s="UDP_Chat" ; "UDP_Chat" Rexx portname
INCLUDE "Net_Protocol_Header.bb2" ; Net protocol constants
INCLUDE "UDPHeader.bb2" ;Standard TCP/UDP library structures
DEFTYPE .w
max_wait=250 ; Time to wait for an acknowledgement (frames)
number_resends=5 ; Number of resends to wait, before disconnecting player
lag_allowance=5 ; Number of frames to add to the current lag, when waiting for an out-of-order packet.
#ACKNOWLEDGE_PACKET=3
#OFFLINE=0
#SERVER=1
#CLIENT=2
packet_number.l=0
online=#OFFLINE
my_number=0
last_message_number.l=0
free_message.l=0
sock.l=-1
security=1 ; level of security warnings (normally 1- show all)
exit=False
game_closing=0
ResetTimer
;********************************************************
NEWTYPE .message_status
number.l ; packet number
ack.w ; has it been received yet?
timestamp.l ; when was it sent?
message.s ; message
resends.w ; how many times has it been re-sent?
player ; which player was it sent too?
End NEWTYPE
NEWTYPE .player_info
status.w ; 0 offline, 1 online
ascii_host_string.s
player_colour.w
score.l
name.s
nick.s
disconnect_requested.w
End NEWTYPE
;*******************************************************
.Dims
Dim messages.message_status(#MESSAGE_ARRAY_SIZE)
Dim host.sockaddrin(#MAX_NUMBER_PLAYERS), hostlen.l(#MAX_NUMBER_PLAYERS)
Dim players.player_info(#MAX_NUMBER_PLAYERS),pingprintx.w(#MAX_NUMBER_PLAYERS)
Dim player_honesty(#MAX_NUMBER_PLAYERS,#MAX_NUMBER_PLAYERS)
Dim player_current_lag(#MAX_NUMBER_PLAYERS)
DEFTYPE .sockaddrin temphost
For a=1 To #MAX_NUMBER_PLAYERS ; this array dimension is for the player number who is claiming another is offline
For b=1 To #MAX_NUMBER_PLAYERS ; this dimension is for the player number who is claimed to be offline
player_honesty(a,b)=False ; initialise array
Next
Next
messages(free_message)\ack=True
INCLUDE "UDPFuncs.bb2" ; basic UDP socket functions
;*******************************************************
.Print_String ; Print a string in window and scroll if necessary
Statement Print_String{text$}
SHARED ypos
If ypos<200
ypos+10
Else
WScroll 10,60,590,220,0,10
EndIf
WLocate 10,ypos
Print text$ ; print string received
End Statement
.Security_Warning
Statement Security_Warning{text$,level}
SHARED security ; security= 0 none, 1 all warnings, 2 medium and severe warnings and 3 only severe warnings
If level>=security ; only print out security warnings if at set security level or higher
Print_String{"Warning: " + text$}
EndIf
End Statement
.Get_Packet_Source ; Check if packet has come from player already logged on.
Function.w Get_Packet_Source{}
SHARED host(),temphost
i=0
Repeat ; check for each player (hostname and socket)
i+1
If host(i)\sin_addr\s_addr=temphost\sin_addr\s_addr AND host(i)\sin_port=temphost\sin_port
exit=1
EndIf
If i=8 AND exit=0 ; if at end of players and no match is found
i=-1
exit=1
EndIf
Until exit=1
Function Return i
End Function
.Get_Ascii_Address ; build a.b.c.d numerical address from long number
Function.s Get_Ascii_Address{address.l}
string_address.l=Inet_NtoA_(address) ; get memory address of ASCII string version of host address (a.b.c.d)
If string_address=0
Function Return ""
EndIf
Repeat ; build ASCII host string
letter.b=(Peek.b(string_address))
If letter<>0
temp$=temp$+Chr$(letter)
EndIf
string_address+1
Until letter=0
Function Return temp$
End Function
.Send_Reliable_Message ; this message is checked to see if it has arrived, and resent if not
Statement Send_Reliable_Message{send_string.s,player} ; if no confirmation can be made, link is considered lost
SHARED messages(),free_message,last_message_number,packet_number.l
send_string.s=Mkl$(packet_number) + send_string.s
messages(free_message)\number=packet_number,False,Ticks,send_string.s,0,player ; log message in message array
If messages(last_message_number)\ack=True
last_message_number=free_message
EndIf
WriteUDP{&send_string.s,Len(send_string.s),player} ; send message
packet_number+1 ; set packet number to next free packet number (+1)
free_message+1
If free_message=#MESSAGE_ARRAY_SIZE+1 Then free_message=0 ; if packet number >#MESSAGE_ARRAY_SIZE then wrap back to 0
End Statement
.Get_Host_By_Name ; get a host structure by name (if exists), from a name server
Function Get_Host_By_Name{host$,port.w,player}
SHARED host(),hostlen()
*a.hostent=gethostbyname_(host$) ; set up destination address to send packets to
If *a.hostent=0
WLocate 10,18
Print " No connection to host "
Function Return False
Else
WLocate 10,18
Print "Type in data, and hit return to send"
EndIf
;Copy Details to our Sockaddrin structure
bb=CopyMem_(*a.hostent\h_addr_list\ItemA,&host(player)\sin_addr,*a.hostent\h_length)
host(player)\sin_port=port ;Set port number
host(player)\sin_family=2 ;Set type to AT_INET
hostlen(player)=SizeOf.sockaddrin ;Get length of structure sockaddrin
Function Return True
End Function
.Get_Host_By_Address ; get a host structure by address (if exists), from a name server
Function.b Get_Host_By_Address{address.l,port,player}
SHARED host(),hostlen()
*a.hostent=gethostbyaddr_(address,4,2) ; check wether host exists- we're not being shammed
If *a.hostent=0
Function Return False
EndIf
bb=CopyMem_(*a.hostent\h_addr_list\ItemA,&host(player)\sin_addr,*a.hostent\h_length) ; copy details to player's host
; newtype to host
host(player)\sin_port=port ;Set port number
host(player)\sin_family=2 ;Set type to AT_INET
hostlen(player)=SizeOf.sockaddrin ;Get length of structure sockaddrin
Function Return True
End Function
.Localhost_Name ; get our internet address- it changes each time we log in to our ISP
Function.s Localhost_Name{}
If OpenFile (0,"ENV:HOSTNAME")
FileInput 0
While NOT Eof(0)
a$=a$+Inkey$
Wend
CloseFile 0
WindowInput 0
Function Return a$
EndIf
Function Return "localhost"
End Function
.Connect_To_Server
Function Connect_to_Server{host.s,port.w}
SHARED online, CP_REQ_CONNECT.s, GAME_NAME.s, NET_PROTOCOL_VERSION.s
If online=#OFFLINE
If Get_Host_By_Name{GTGetString(0,51), GTGetInteger(0,52),1}=True
Print_String{"Attempting to connect to Server"}
send$=Mkl$(0) + CP_REQ_CONNECT.s + GAME_NAME.s + Chr$(0) + NET_PROTOCOL_VERSION.s ; "0000" is a Pad for packet number
WriteUDP{&send$,Len(send$),1} ; se